package com.googlecode.stemwijzer.client.presenter;

import net.customware.gwt.presenter.client.EventBus;
import net.customware.gwt.presenter.client.place.Place;
import net.customware.gwt.presenter.client.widget.WidgetDisplay;

import com.allen_sauer.gwt.log.client.Log;
import com.google.gwt.event.dom.client.ClickEvent;
import com.google.gwt.event.dom.client.ClickHandler;
import com.google.gwt.event.dom.client.HasClickHandlers;
import com.google.gwt.user.client.rpc.AsyncCallback;
import com.google.inject.Inject;
import com.googlecode.stemwijzer.client.StemwijzerServiceAsync;
import com.googlecode.stemwijzer.client.event.ExceptionEvent;
import com.googlecode.stemwijzer.client.event.ResetSessionEvent;
import com.googlecode.stemwijzer.shared.model.Questionnaire;

public class ResultsPresenter extends AbstractPresenter<ResultsPresenter.Display> {

	public interface Display extends WidgetDisplay {
		void showResults(Questionnaire results);

		HasClickHandlers getResetSession();
	}

	private final StemwijzerServiceAsync service;

	public static final Place PLACE = new Place("ResultsPresenter");

	@Inject
	public ResultsPresenter(Display display, EventBus eventBus, StemwijzerServiceAsync service) {
		super(display, eventBus);
		this.service = service;

		bind();
	}

	@Override
	public Place getPlace() {
		return PLACE;
	}

	@Override
	protected void onBind() {
		display.getResetSession().addClickHandler(new ResetSessionClickHandler());
	}

	@Override
	public void revealDisplay() {
		Log.debug("Displaying results");

		display.startProcessing();

		service.getQuestionnaire(new GetQuestionnaireCallback());
	}

	private final class ResetSessionClickHandler implements ClickHandler {
		@Override
		public void onClick(ClickEvent event) {
			service.resetSession(new ResetSessionCallback());
		}
	}

	private final class GetQuestionnaireCallback implements AsyncCallback<Questionnaire> {

		@Override
		public void onSuccess(Questionnaire questionnaire) {
			display.stopProcessing();
			if (questionnaire == null) {
				eventBus.fireEvent(new ExceptionEvent("Ongeldig resultaat"));
			}
			display.showResults(questionnaire);
		}

		@Override
		public void onFailure(Throwable t) {
			display.stopProcessing();
			eventBus.fireEvent(new ExceptionEvent("Resultaten konden niet worden opgehaald"));
		}
	}

	private final class ResetSessionCallback implements AsyncCallback<Questionnaire> {

		@Override
		public void onSuccess(Questionnaire questionnaire) {
			if (questionnaire == null) {
				eventBus.fireEvent(new ExceptionEvent("Kon sessie niet herinitialiseren"));
			} else {
				eventBus.fireEvent(new ResetSessionEvent());
				unbind();
			}
		}

		@Override
		public void onFailure(Throwable t) {
			eventBus.fireEvent(new ExceptionEvent("Fout bij herinitialiseren sessie", t));
		}
	}
}
